﻿namespace c_基础完成版
{
    internal class Program
    {
        static void Main(string[] args)
        {
            #region 1 控制台设置
            int w = 50;
            int h = 30;
            ConsoleInit(w, h);
            #endregion
            #region 2 场景
            Secece nowSecece = Secece.begin;
            while (true)
            {
                switch (nowSecece)
                {
                    case Secece.begin:
                        //开始场景
                        Console.Clear();
                        BeginSecence(w, h, ref nowSecece);
                        break;
                    case Secece.game:
                        //游戏场景
                        Console.Clear();
                        GameSence(w, h, ref nowSecece);
                        break;
                    case Secece.end:
                        //结束场景
                        Console.Clear();
                        BeginSecence(w, h, ref nowSecece);
                        break;
                    default:
                        break;
                }

            }
            #endregion
        }
        #region 1 控制台设置
        static void ConsoleInit(int w, int h)
        {
            //关闭光标
            Console.CursorVisible = false;
            //窗口大小和缓冲区大小
            Console.SetWindowSize(w, h);
            Console.SetBufferSize(w, h);
        }
        #endregion

        #region 3 场景切换
        static void BeginSecence(int w, int h, ref Secece nowSecece)
        {
            Console.SetCursorPosition(nowSecece == Secece.begin ? w / 2 - 3 : w / 2 - 4, 8);
            Console.Write(nowSecece == Secece.begin ? "飞行棋" : "游戏结束");
            int NowSelindex = 0;
            bool isSececeGame = false;
            while (true)
            {
                Console.SetCursorPosition(w / 2 - 4, 13);
                Console.ForegroundColor = NowSelindex == 0 ? ConsoleColor.Red : ConsoleColor.White;
                Console.Write(nowSecece == Secece.begin ? "开始游戏" : "继续游戏");

                Console.SetCursorPosition(w / 2 - 4, 15);
                Console.ForegroundColor = NowSelindex == 1 ? ConsoleColor.Red : ConsoleColor.White;
                Console.Write("退出游戏");
                switch (Console.ReadKey(true).Key)
                {
                    case ConsoleKey.W:
                        NowSelindex--;
                        if (NowSelindex < 0)
                        {
                            NowSelindex = 0;
                        }
                        break;
                    case ConsoleKey.S:
                        NowSelindex++;
                        if (NowSelindex > 1)
                        {
                            NowSelindex = 1;
                        }
                        break;
                    case ConsoleKey.J:
                        if (NowSelindex == 0)
                        {
                            nowSecece = Secece.game;
                            isSececeGame = true;
                        }
                        else
                        {
                            Environment.Exit(0);
                        }
                        break;
                }
                if (isSececeGame == true)
                    break;
            }
        }
        #endregion
        #region 游戏场景
        static void GameSence(int w, int h, ref Secece nowSecece)
        {
            bool isGameOver = false;
            //绘制不变信息
            DrawWall(w, h);
            //地图绘制
            Map map = new Map(13, 2, 100);
            map.Drawmap();
            //绘制玩家
            Player player = new Player(E_Player.Player, 0);
            Player computer = new Player(E_Player.Computer, 0);
            DrawPlayer(player, computer, map);
            //游戏逻辑
            while (true)
            {
                //按任意键
                Console.ReadKey(true);
                //投色子
                isGameOver = RandomMove(ref player, ref computer, map, h, w);
                //画出来
                map.Drawmap();

                DrawPlayer(player, computer, map);
                if (isGameOver == true)
                {
                    //卡住程序 让玩家按任意键 
                    Console.ReadKey(true);
                    //改变场景ID
                    nowSecece = Secece.end;
                    break;
                }

                //电脑
                //按任意键
                Console.ReadKey(true);
                //投色子
                isGameOver = RandomMove(ref computer, ref player, map, h, w);
                //画出来
                map.Drawmap();

                DrawPlayer(player, computer, map);
                if (isGameOver == true)
                {
                    //卡住程序 让玩家按任意键 
                    Console.ReadKey(true);
                    //改变场景ID
                    nowSecece = Secece.end;
                    break;
                }
            }
        }
        #endregion
        #region 4绘制不变信息
        static void DrawWall(int w, int h)
        {
            Console.ForegroundColor = ConsoleColor.Red;
            for (int i = 0; i < w; i += 2)
            {//横着的墙
                Console.SetCursorPosition(i, 0);
                Console.Write("■");
                Console.SetCursorPosition(i, h - 1);
                Console.Write("■");
                Console.SetCursorPosition(i, h - 6);
                Console.Write("■");
                Console.SetCursorPosition(i, h - 11);
                Console.Write("■");
            }
            //竖着墙
            for (int j = 0; j < h; j++)
            {
                Console.SetCursorPosition(0, j);
                Console.Write("■");
                Console.SetCursorPosition(w - 2, j);
                Console.Write("■");
            }
            //文字信息
            Console.ForegroundColor = ConsoleColor.White;
            Console.SetCursorPosition(2, h - 10);
            Console.Write("□:普通格子");

            Console.ForegroundColor = ConsoleColor.Blue;
            Console.SetCursorPosition(2, h - 9);
            Console.Write("‖:暂停，一回合不懂");

            Console.ForegroundColor = ConsoleColor.Red;
            Console.SetCursorPosition(26, h - 9);
            Console.Write("●:炸弹，倒退5格");

            Console.ForegroundColor = ConsoleColor.Yellow;
            Console.SetCursorPosition(2, h - 8);
            Console.Write("¤:时空隧道，随机倒退，暂停，换位置");

            Console.ForegroundColor = ConsoleColor.Cyan;
            Console.SetCursorPosition(2, h - 7);
            Console.Write("★:玩家");

            Console.ForegroundColor = ConsoleColor.Magenta;
            Console.SetCursorPosition(12, h - 7);
            Console.Write("▲:电脑");

            Console.ForegroundColor = ConsoleColor.DarkGreen;
            Console.SetCursorPosition(22, h - 7);
            Console.Write("◎:玩家和电脑重合");

            Console.ForegroundColor = ConsoleColor.White;
            Console.SetCursorPosition(2, h - 5);
            Console.Write("按任意键开始扔色子");
        }
        #endregion
        #region 7 绘制玩家
        static void DrawPlayer(Player player, Player computer, Map map)
        {
            if (player.index == computer.index)
            {
                Console.SetCursorPosition(map.grids[player.index].pos.w, map.grids[player.index].pos.h);
                Console.ForegroundColor = ConsoleColor.DarkGreen;
                Console.Write("◎");
            }
            else
            {
                player.DrawPlayer(map);
                computer.DrawPlayer(map);
            }
        }
        #endregion
        #region 8 投色子
        static bool RandomMove(ref Player p1, ref Player p2, Map map, int h, int w)
        {
            Console.SetCursorPosition(2, h - 5);
            Console.Write("                                   ");
            Console.SetCursorPosition(2, h - 4);
            Console.Write("                                   ");
            Console.SetCursorPosition(2, h - 3);
            Console.Write("                                   ");
            Console.SetCursorPosition(2, h - 2);
            Console.Write("                                   ");
            Console.ForegroundColor = p1.player == E_Player.Player ? ConsoleColor.Cyan : ConsoleColor.Magenta;
            if (p1.isPause)
            {
                Console.SetCursorPosition(2, h - 5);
                Console.WriteLine("该回合暂停");
                Console.SetCursorPosition(2, h - 4);
                Console.WriteLine("请按任意键让{0}投色子", p1.player == E_Player.Player ? "电脑" : "你自己");
                p1.isPause = false;
                return false;
            }
            Random r = new Random();
            int randNum = r.Next(1, 7);
            p1.index += randNum;
            Console.SetCursorPosition(2, h - 5);
            Console.WriteLine("{0}投出了{1}", p1.player == E_Player.Player ? "你" : "电脑", randNum);
            if (p1.index >= map.grids.Length - 1)
            {
                Console.SetCursorPosition(2, h - 4);
                p1.index = map.grids.Length - 1;
                Console.WriteLine("{0}", p1.player == E_Player.Player ? "恭喜你赢了" : "遗憾电脑赢了");
                Console.SetCursorPosition(2, h - 3);
                Console.Write("请按任意键结束游戏");
                return true;
            }
            switch (map.grids[p1.index].type)
            {
                case E_Grid.Normal:
                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}到了一个安全位置", p1.player == E_Player.Player ? "你" : "电脑");
                    Console.SetCursorPosition(2, h - 3);
                    Console.Write("请按任意键，让{0}开始扔色子", p1.player == E_Player.Player ? "电脑" : "你");
                    break;
                case E_Grid.Boom:
                    p1.index -= 5;
                    if (p1.index < 0)
                        p1.index = 0;
                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}踩到了炸弹，退后5格", p1.player == E_Player.Player ? "你" : "电脑");
                    Console.SetCursorPosition(2, h - 3);
                    Console.Write("请按任意键，让{0}开始扔色子", p1.player == E_Player.Player ? "电脑" : "你");
                    break;
                case E_Grid.Pause:
                    p1.isPause = true;
                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}到达了暂停点，你需要暂停一回合", p1.player == E_Player.Player ? "你" : "电脑");
                    Console.SetCursorPosition(2, h - 3);
                    Console.Write("请按任意键，让{0}开始扔色子", p1.player == E_Player.Player ? "电脑" : "你");
                    break;
                case E_Grid.Tunnel:
                    Console.SetCursorPosition(2, h - 4);
                    Console.Write("{0}踩到了时空隧道", p1.player == E_Player.Player ? "你" : "电脑");
                    randNum = r.Next(1, 91);
                    if (randNum <= 30)
                    {
                        p1.index -= 5;
                        if (p1.index < 0)
                            p1.index = 0;
                        Console.SetCursorPosition(2, h - 3);
                        Console.Write("触发倒退5格");
                    }
                    else if (randNum <= 60)
                    {
                        Console.SetCursorPosition(2, h - 3);
                        Console.Write("触发暂停一回合");
                        p1.isPause = true;
                    }
                    else
                    {
                        int tmp = p1.index;
                        p1.index = p2.index;
                        p2.index = tmp;
                        Console.SetCursorPosition(2, h - 3);
                        Console.Write("惊喜，惊喜，双方交换位置");
                    }
                    Console.SetCursorPosition(2, h - 2);
                    Console.Write("请按任意键，让{0}开始扔色子", p1.player == E_Player.Player ? "电脑" : "你");
                    break;
            }
            return false;
        }
        #endregion
    }


    #region 2 场景枚举
    enum Secece
    {
        begin,
        game,
        end,
    }
    #endregion 
    #region 5格子的结构体和枚举
    enum E_Grid
    {
        Normal,
        Boom,
        Pause,
        Tunnel,
    }
    struct Vector2
    {
        public int w;
        public int h;
        public Vector2(int w, int h)
        {
            this.w = w; this.h = h;
        }
    };
    struct Grid
    {
        public E_Grid type;
        public Vector2 pos;
        public Grid(E_Grid type, int w, int h)
        {
            this.type = type;
            pos.h = h;
            pos.w = w;
        }
        public void Draw()
        {
            Console.SetCursorPosition(pos.w, pos.h);
            switch (type)
            {
                case E_Grid.Normal:
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.Write("□");
                    break;
                case E_Grid.Boom:
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.Write("●");
                    break;
                case E_Grid.Pause:
                    Console.ForegroundColor = ConsoleColor.Blue;
                    Console.Write("‖");
                    break;
                case E_Grid.Tunnel:
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.Write("¤");
                    break;
            }
        }
    };
    #endregion
    #region 6地图结构
    struct Map
    {
        public Grid[] grids;
        public Map(int w, int h, int num)
        {
            Random r = new Random();
            int randdomNum;
            grids = new Grid[num];
            int indexX = 0, indexY = 0;
            int pluss = 2;
            for (int i = 0; i < grids.Length; i++)
            {
                randdomNum = r.Next(0, 101);
                if (randdomNum == 0 || randdomNum == num - 1 || randdomNum <= 85)
                {
                    grids[i].type = E_Grid.Normal;
                }
                else if (randdomNum > 85 && randdomNum < 90)
                {
                    grids[i].type = E_Grid.Boom;
                }
                else if (randdomNum > 90 && randdomNum < 95)
                {
                    grids[i].type = E_Grid.Pause;
                }
                else
                {
                    grids[i].type = E_Grid.Tunnel;
                }
                grids[i].pos = new Vector2(w, h);
                if (indexX == 10)
                {
                    h += 1;
                    indexY++;
                    if (indexY == 2)
                    {
                        indexY = 0;
                        indexX = 0;
                        pluss = -pluss;
                    }
                }
                else
                {
                    indexX++;
                    w += pluss;
                }
            }
        }
        public void Drawmap()
        {
            for (int i = 0; i < grids.Length; i++)
            {
                grids[i].Draw();
            }
        }
    };
    #endregion
    #region 7 玩家枚举和结构体
    enum E_Player
    {
        Player,
        Computer,
    }
    struct Player
    {
        public E_Player player;
        public int index;
        public bool isPause;
        public Player(E_Player player, int index)
        {
            this.player = player;
            this.index = index;
            isPause = false;
        }
        public void DrawPlayer(Map map)
        {
            Grid grid = map.grids[index];
            Console.SetCursorPosition(grid.pos.w, grid.pos.h);
            switch (player)
            {
                case E_Player.Player:
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.Write("★");
                    break;
                case E_Player.Computer:
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.Write("▲");
                    break;
            }
        }
    };
    #endregion

}
